/*
 * szymon.pilkowski @ gmail.com
 * 
 * simple javascript benchmark
 * 
 * ==
 * 
 * TODO:
 * 
 * - code versions archive and comparision
 * - insert html
 * - precision?
 * - about page
 */

var jsb_iterations = 50;

var graph, graph2, bar, cons;

function compare(a, b) {
	
  if (a[1] < b[1])
     return -1;
  if (a[1] > b[1])
     return 1;
  return 0;
  
}


function clog(t) {
		
	$(cons).text( $(cons).text() + "# " + t + "\n" )
	
}

function jsb_timestamp() {
	
    var jsb_time = new Date();
	jsb_time = jsb_time.getTime();

    return jsb_time;

}

function jsb_benchmark() {
	$("#console").text("")
	graphdata = [ ];
	graphdata2 = [ ];
	extreme = 0;
	extreme2 = 0;
	extreme3 = 0;
	jsb_procTime = 0;
	iColor = myColors[runs];
	xColor = myColors[runs+1];
	runs++;
	
	jsb_tmpIt = $("#iter").attr("value");
	if (jsb_tmpIt > 0) { jsb_iterations = jsb_tmpIt }
	var jsb_code = $("#code").attr("value");
	if (!jsb_code) {
		alert("Empty field. Stopping.");
		return false;
	}
	if (jsb_code.match(/alert\(/)) {
		
		alert("Alerts detected. Saving yourself from yourself. Stopping.")
		return false;
		
	}
	if ((jsb_code == null) || (jsb_code == undefined) || (jsb_code.length == 0) || (jsb_code == "")) {
		return false;
	}
	for (jsb_x=0; jsb_x < jsb_iterations; jsb_x++) {
		
		added = false;
		var single_startTime = jsb_timestamp();
        
		(function($) {
			
			eval(jsb_code);
			
		})(jQuery);
		
		var single_endTime = jsb_timestamp();
		var single_procTime = single_endTime - single_startTime;
		jsb_procTime = jsb_procTime + single_procTime;
		graphdata.push([jsb_x, single_procTime])
		
		if (single_procTime > extreme2) {
			
			extreme2 = single_procTime;

		}
					

		/*
		 * graphdata2 - wykres slupkowy
		 */
		
		if (graphdata2.length > 0) {

				if (graphdata2[single_procTime]) {
					graphdata2[single_procTime][0] = single_procTime;
					graphdata2[single_procTime][1]++;
					
					if (graphdata2[single_procTime][1] > extreme3) {
			
						extreme3 = graphdata2[single_procTime][1];
					}
					
					graph2iter++;
				} else {

					graphdata2[single_procTime]	= [];
					graphdata2[single_procTime] = [single_procTime, 1]				
				}

			
		} else {

			graphdata2[single_procTime] = [single_procTime, 1]
			graph2iter++;
			
		}
		
		
		
		clog(single_procTime)
	}

	var jsb_singleTime = jsb_procTime / jsb_iterations;
	
	var jsb_evalStartTime = jsb_timestamp();
	for(eval_x=0;eval_x < jsb_iterations; eval_x++) {
		eval("")
	}
	var jsb_evalEndTime = jsb_timestamp();
	var jsb_evalTime = jsb_evalEndTime - jsb_evalStartTime;

	var jsb_predictTime = (jsb_procTime - jsb_evalTime) / jsb_iterations;
	
	extreme = 0;

	sorteddata = graphdata.slice();
	sorteddata.sort(compare)
	tmp = sorteddata.pop(); 
	tmp = tmp[1];
	extreme = tmp + tmp / 5;
	

	$("#result").html(jsb_iterations + " iterations, " + jsb_procTime + " milliseconds. <br />Approximately <strong>" + jsb_singleTime + " </strong>per one script execution. <br />Predicted (and probably false) eval-free time: " + jsb_predictTime + " ms");
	
	plot = $.plot($(graph), [{
		data: graphdata,
		color: iColor,
		shadowSize: 6,
		label: "iterations / time(ms)"
	}], 
		{
		legend: {
			show: true
		},
		yaxis: { max: extreme }
		});
	plot2 = $.plot($(graph2), [{
		data: graphdata2,
		color: xColor,
		label: "time(ms) / number of occurencies",
		bars: { show: true },
		lines: { show: false }
	}], {
		yaxis: { max: extreme3 + (extreme3 / 5)},
		xaxis: { ticks: 10, min: 0, max: extreme2 + (extreme2 / 5) }
		});	
		$(cons).prepend("<a href='#' id='cons-expand'>debug details</a><br /><br />")
		$("#cons-expand").click( function() {
			
			if (expanded) {
				
				$(this).parent().css("height", 0)
				expanded = false
				
			} else {
	
				$(this).parent().css("height", "auto")
				expanded = true	
				
			}
			
			
		})
	}

$(document).ready( function() {

	$("#run").click( function() {
		jsb_benchmark();
	});
	
	cons = $("#console")
	graph = $("#graph")
	graph2 = $("#graph2")
 	bar = $("#bar")
	$(cons).text("")
	
	myColors = ["#f2cf6f", "#4de43d", "#20becc", "#c1521b", "#ff0000"]

	graph2iter = 0;
	runs = 0;
	expanded = false;
	
})